﻿// WaveTable.cs (c) Copyright 2009, Mike Hodnick : www.hodnick.com
// This in-memory wave table implementation was built with help 
// from Charles Petzold (www.charlespetzold.com)
	
using System;

namespace Kindohm.KSynth.Library
{
    public class WaveTable
    {
        static bool initialized;
        public static short[] SineWaveForm = new short[65536];
        public static double[] SineModWaveForm = new double[65536];
        public static short[] SquareWaveForm = new short[65536];
        public static double[] SquareModWaveForm = new double[65536];
        public static short[] SawWaveForm = new short[65536];
        public static double[] SawModWaveForm = new double[65536];
        public static short[] TriangleWaveForm = new short[65536];
        public static double[] TriangleModWaveForm = new double[65536];

        public static void InitializeWaveForms()
        {
            if (initialized)
                return;

            for (ushort i = 0; i < ushort.MaxValue; i++)
            {
                double ratio = (double)i / ushort.MaxValue;

                // oscillator arrays
                SineWaveForm[i] = (short)(short.MaxValue *
                        Math.Sin(2 * Math.PI / ushort.MaxValue * i));
                SawWaveForm[i] = (short)(short.MinValue + i);
                TriangleWaveForm[i] = (short)(i < (ushort.MaxValue) ? 1 * short.MinValue + 2 * i :
                                                                             3 * short.MaxValue - 2 * i);
                SquareWaveForm[i] = i < (ushort)short.MaxValue ? short.MinValue : short.MaxValue;

                // modulator arrays
                SineModWaveForm[i] = (double)(Math.Sin(2 * Math.PI * ratio));
                SawModWaveForm[i] = (double)(-1 + (2 * ratio));
                TriangleModWaveForm[i] = (double)(i < (ushort.MaxValue) ? 1 * -1 + 2 * ratio :
                                                             3 * 1 - 2 * ratio);
                SquareModWaveForm[i] = i < (double)short.MaxValue ? (double)-1 : (double)1;

            }

            // last oscillator slots
            SineWaveForm[65535] = (short)(short.MaxValue *
                Math.Sin(2 * Math.PI));
            SquareWaveForm[65535] = short.MaxValue;
            TriangleWaveForm[65535] = TriangleWaveForm[65534];  //hack
            SawWaveForm[65535] = (short)(short.MinValue + ushort.MaxValue);

            // last modulator slots
            SineModWaveForm[65535] = (short)(Math.Sin(2 * Math.PI));
            SawModWaveForm[65535] = (short)(1);
            TriangleModWaveForm[65535] = TriangleModWaveForm[65534];  //hack
            SquareModWaveForm[65535] = 1;

            initialized = true;
        }
    }
}
